package Modelo;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;




public class Liga {
	
	
	//atributos

	private ArrayList<Arbitro> Arbitros;
	private ArrayList<Equipo> Equipos;
	private ArrayList<Partido> Partidos;
	private ArrayList<Arbitro> Auxarbitro;
	private ArrayList<Equipo> Auxequipocasa;
	private ArrayList<Equipo> Auxequipovisita;
	private ArrayList<String> codigo;
	private ArrayList<Equipo> casa;
	private ArrayList<Equipo> visita;
	private ArrayList<String> fechas;
	private ArrayList<Jugador> auxJugador;
	private ArrayList<Jugador> auxJugador2;
	
	

	//Constructor
	
	public Liga() {
		super();
		
		Arbitros = new ArrayList<Arbitro>();
		Equipos = new ArrayList<Equipo>();
		Partidos= new ArrayList<Partido>();
		
		
		
		// TODO Auto-generated constructor stub
	}
	//carga partidos de la liga
	public void cargarPartido(Partido partido)
	{
		this.Partidos.add(partido);
	}
	
	//Carga arbitros de la liga
	public void cargarArbitro (Arbitro arbitro){
		
		this.Arbitros.add(arbitro);
				
	}
	//Carga los equipos de la liga
	
	public void cargarEquipo (Equipo equipo){
		
		this.Equipos.add(equipo);
	}
	//cuenta la cantidad de partidos que existe en el arraylistpartido
	
	public int contarPartidos()
	{
		return this.Partidos.size();
	}
	
	//cuenta la cantidad de arbitros que existen en el arraylistarbitro
	
	public int contararbitro (){
		
		return this.Arbitros.size();
	}
	
	//cuenta la cantidad de equipos que existe en el arraylisequipo
	
	public int contarequipo (){
		
		return this.Equipos.size();
	}
	
	//retorna los partidos del arraylistpartido, utilizado para realizar las consultas
	
	
	public ArrayList<Partido> getPartidos()
	{
		if(this.contarPartidos()>0)
		{
			return this.Partidos;
			 
		}
		else
			return null;
	}
	
	//retorna los equipos del arraylistequipo utilizado para el consultar
	
	
	
	public ArrayList<Equipo> getEquipos(){
		if (this.contarequipo() > 0){
			
			return this.Equipos;
		}
		else
			return null;
		
	}
	
	
	
	//llena todos los partidos de toda la liga
	public void llenarCasaVisitante()
	{
		//arraylists auxiliares me mantinen todos los partidos
		//que jugaran en toda la liga
		Auxequipocasa= new ArrayList<Equipo>();
		Auxequipovisita= new ArrayList<Equipo>();
		//variables locales
		Equipo aux1,aux2;
		
		//for que llena las diferentes combinaciones para los partidos
		for(int i=0; i<contarequipo(); ++i)
		{
			aux1= Equipos.get(i);
			 
			for( int j= i+1; j<contarequipo();++j)
			{
				aux2= Equipos.get(j);
				this.Auxequipocasa.add(aux1);
				this.Auxequipovisita.add(aux2);
			
			}
			
			
		}
		//segunda vuelta de las combinaciones para que todos los equipos se
		//enfrenten dos veces
		for(int i=0; i<contarequipo(); ++i)
		{
			aux1= Equipos.get(i);
			 
			for( int j= i+1; j<contarequipo();++j)
			{
				aux2= Equipos.get(j);
				this.Auxequipocasa.add(aux2);
				this.Auxequipovisita.add(aux1);
			
			}
		
		}
		
		
	}
	
//genera los goles aleatoriamente se multiplica por 5 xq son de
	//0 a 5 goles por equipo
	
	public int generarGoles()
	{
	 int goles=(int)Math.floor(Math.random()*5);
	 return goles;
	}
	
	
//busca un equipo en el arraylist equipos y retorna el indice
	
	public int buscarEquipo (String codigo){
		
		//variables locales
		int posicion = 0 ;
		int i = 0;
		boolean encontrado = false;
		//while que revisa todo el arraylistequipo y busca la posicion de ese equipo
		//y retorna la posicion
		
		while ((i < this.contarequipo()) && (encontrado == false)) {
			
			if (this.Equipos.get(i).getCodigo().equals(codigo) )
			  {
				posicion = i;
			    encontrado = true;
			  }
				
			else
				++i;
		}
		
		
		return posicion;
		
	}

//buscar si el codigo del equipo existe para que no se introduzca
	//dos veces el mismo equipo
public boolean buscarCodigoEquipo (String codigo){
		
		//variables locales
		
		int i = 0;
		boolean encontrado = false;
		
		while ((i < this.contarequipo()) && (encontrado == false)) {
			
			if (this.Equipos.get(i).getCodigo().equals(codigo) )
			  {
				
			    encontrado = true;
			  }
				
			else
				++i;
		}
		
		
		return encontrado;
		
	}	

//buscar el codigo del arbitro pero retorna true si lo encuentra
//y false si esa cedula que se ingresa no es encontrado es utilizado en
//el validar para que no introduzcan dos veces el mismo arbitro.

public boolean buscarCodigoArbitro (String cedula){
		
		
		//variables locales
		int i = 0;
		boolean encontrado = false;
		
		while ((i < this.contararbitro() ) && (encontrado == false)) {
			
			if (this.Arbitros.get(i).getCedula().equals(cedula) )
			  {
				
			    encontrado = true;
			  }
				
			else
				++i;
		}
		
		
		return encontrado;
		
	}

	
	
	
	
	
	
//busca un arbitro en el arraylist arbitro y retorna el indece
	
public int buscarArbitro (String cedula){
		
		
		int posicion = 0 ;
		int i = 0;
		boolean encontrado = false;
		
		while ((i < this.contararbitro()) && (encontrado == false)) {
			
			if (this.Arbitros.get(i).getCedula().equals(cedula))
			  {
				posicion = i;
			    encontrado = true;
			  }
				
			else
				++i;
		}
		
		
		return posicion;
		
	}


//asigna goles a los jugadores es una macro que se utiliza
//para asignarle los goles generados aleatoriamente a los jugadores
//que conforman el equipo, del que se pasa el codigo por parametro
	
	
	public void asignarGoles(int goles,String codigo,ArrayList<Jugador> jugador)
	
	{
		//utilizo el metodo buscar equipo para que me de la posicion
		//donde esta en el arraylisequipo
	
		int posicion =buscarEquipo (codigo) ;
		//for hasta la cantidad de goles generados aleatoriamente en otro metodo
		
	
		for(int i=0; i<goles; i++)
		{
			//genera aleatoriamente el indice al jugador que se le
			//va a asignar los goles
			int indice= (int)Math.floor(Math.random()*Equipos.get(posicion).getJugadores().size()); 
			
			 //llena el arraylist auxiliar de jugadores 
			jugador.add(Equipos.get(posicion).getJugadores().get(indice));
			
			
		}
	}
	
// buscar jugador y me retorna la posicion 
	public int buscarJugador(String cedula, int posicion)
	{
		//variables locales
		boolean encontrado=false;
		int i=0,posicion1=0;
		while(i<(this.Equipos.get(posicion).getJugadores().size()) && (encontrado ==false))
		{
			if(this.Equipos.get(posicion).getJugadores().get(i).getCedula().equals(cedula))
			{
				posicion1= i;
				encontrado= true;
			}
			else
				++i;
			
		}
		return posicion1;
	}
		
		
//llena el auxiliar de los codigos para todos los partidos 
	
	public void llenarArraylistdecodigo ()
	{
		//instancia arraylist auxiliar
		codigo= new ArrayList<String>();
		int n= contarequipo();
		//control contiene el total de los partidos que debe generar en toda la liga
		int control= n*(n-1);
		for(int i=0;i<control;++i)
		{
			this.codigo.add("00"+i);
		}
		
	}
	
	
//suma el n a la fecha actual para generar los diferentes fecha de las
	//partidos, todos los jugadores van a jugar el mismo dia de la semana
	public String sumarFecha(Date fechaActual, int n)
	{
		SimpleDateFormat formato= new SimpleDateFormat("dd/MM/yyyy");
		Date fecha;
		Calendar cal = Calendar.getInstance();
		cal.setTime(fechaActual);
		//suma la n a la fecha actual
		cal.add(Calendar.DAY_OF_YEAR, n);
		fecha= cal.getTime();
		String f= formato.format(fecha);
		return f;
	}
	
	
//llena arraylist auxiliar que va a contener todas las fechas
	//de los partidos que se van a jugar en la en la liga
	public void llenarFechas()
	{
		//instancia el arraylist auxiliar
		fechas = new ArrayList<String>();
		int n= contarequipo();
		//n1 es el total de partidos a generarse en la liga
		int n1= n*(n-1);
		//n2 es el numero de semana que se van jugar
		int n2= n1/2;
		//m variable local que me contiene los dias que se les va a sumar a la fecha actual
		int m=0;
		Date fecha= new Date();
		
		for(int i=0; i<= n2;++i)
		{
			
			m+=7;
			//llena el arraylist auxiliar invocando el metodo que suma las fechas
			fechas.add(sumarFecha(fecha,m));
			
		}
	}
	//valida que la cantidad de arbitro sea sufuciente para generar
	//los partidos de una semana ya que no se pueden repetir los
	//arbitros en los mismo juegos
	
	public boolean validarArbitros()
	{
		int n= contarequipo();
		//total de partidos a generar en una semana
		int n1 = n/2;
		int arb= contararbitro();
		
		if ( arb >= n1)
			return true;
		
		else
			return false;		
		
	}
	
	
//metodo que genera los partidos que se van a jugar en toda la liga
	public void generarPartido()
	{
		//variables locales
		//n total de equipos,control el total de partidos 
		//n1 cantidad de juegos en una semana
		//controlfecha es un indice que controlas las fechas
		
		int n= contarequipo();
		int control = n*(n-1);
		Equipo aux,aux2;
		int n1 = n/2;
		int controlarfecha = 0;
		int i=0;
		// for que llena todos los partidos 
			while(i<control)
			{
				//r y j variables locales que controlan 
				//el while que me llena los partidos de una semana
				int r=0,j=0;
				// se instancias los arraylist auxiliares que se utilizan
				//para llenar los arbitros, y equipos de una semana
				Auxarbitro = new ArrayList<Arbitro>();
				
				
				casa= new ArrayList<Equipo>();
				visita= new ArrayList<Equipo>();
				
				
				//while que llena los equipos que juegan en una semana
				while((j<Auxequipocasa.size())&&(r<n1))
				{
					//se le asigna a las variables locales los los equipos 
					//que se encuentran el los arraylist que contienen todos los
					//partidos que se van a enfrentar en la liga
					aux= Auxequipocasa.get(j);
					aux2 = Auxequipovisita.get(j);
					//variables locales
					
					boolean encontrado= false, encontrado2=false;
					//for que se utiliza para comparar lo que tiene las
					//variables aux y aux2 llenadas anteriormente
					//para que no se repita con los equipos que se encuentran
					//en la semana
					for(int p=0; p<casa.size();p++)
					{
						//se pregunta en los dos equipos si se encuentra en uno o
						//otro arraylist se coloca la variable en true para que
						//dicho equipo no sea ingresado de nuevo en la semana
						//ya que un equipo puede jugar una semana
						if((aux== casa.get(p)) || (aux==visita.get(p)))
								{
							      encontrado= true;
							
								}
						if((aux2==visita.get(p))||(aux2==casa.get(p)))
						{
							encontrado2= true;
						}
					}
					//cuando sale del for pregunta si encontro el equipo
					//de no se encontrado se llenan los arraylist auxiliares
					//que llenan lo equipos de una semana
					if((encontrado ==false) && (encontrado2==false))
					{
						casa.add(Auxequipocasa.remove(j));
						visita.add(Auxequipovisita.remove(j));
						//aumenta r que controla el total de equipos que se
						//deben generar en una semana
						++r;
												
					}
					//se esta eliminando los equipos de las Auxequipovisita y Auxequipo casa
					//y el indice disminuye por lo tanto se debe 
					// preguntar si elimino o no por eso este if por si remueve no incremete la j aqui..
					if((encontrado== true) || (encontrado2 == true))
					{
						++j;
					}
					
					
				}
				//while que me llena los arbitros de una semana
				// variables locales k controla el k que indica
				//la cantidad de arbitros que se deben generar en una semana
				int k=0;
				Arbitro aux3;
				while(k<n1)
				{
					//genera un indice aleatorio para asignar aleatoriamente
					//los arbitros que van a jugar en una semana
					int indice=(int)Math.floor(Math.random()*contararbitro());
					//le asigna a aux3 variable local el equipo que se encuentra en el 
					//indice generado aleatoriamente
					aux3 = Arbitros.get(indice);
					//variable local que me cambia si ya se encuentra dicho 
					//arbitro asignado a los partidos de esa semana
					boolean encontrado= false;
					//for que busca el arbitro en el arraylist auxiliar de arbitros
					
					for(int p=0; p<Auxarbitro.size();++p)
					{
						if(aux3== Auxarbitro.get(p))
						{
							encontrado=true;
						}
						
					}
					//if que pregunta si el arbitro ya fue asognado en la semana
					//de ser false se llena el auxiliar arbitro que me tiene
					//los arbitros de una semana
					if(encontrado==false)
					{
						Auxarbitro.add(aux3);
						++k;
					}
					
				}
				//while que me genera los partidos pero de una semana
				//g variable local que me controla el while
				//n1 cantidad de juegos que debe generar en una semana
				int g=0;
				while(g<n1)
				{
					//arraylist auxiliares que me van a contener los 
					//jugadores a los que se les va a asignar los goles
					//de los equipos, los instancio para que cada vez
					//que llene un partido, llene los jugadores de ese partido
					auxJugador = new ArrayList<Jugador>();
					auxJugador2= new ArrayList<Jugador>();
					//variables locales para crear el objeto partido y cargarlo
					String codigo;
					String fecha;
					Equipo casa;
					Equipo visita;
					Arbitro arbitro;
					String cod,cod2;
					
				    //variables donde se guardan los goles que se generan 
					//aleatoriamente
					int au1=0,au2=0;
					//le asigno a au1 los goles aleatorios que va a tener casa
					//se utiliza el metodo que genera los goles aleatoriamente
					au1=generarGoles();
					//tomo los codigo para buscar el equipo al que le voy a buscar los jugadores
					cod=this.casa.get(g).getCodigo();
					cod2=this.visita.get(g).getCodigo();
					//asigno goles utilizando el metodo de asignar goles
					//se le manda por parametro los arraylist auxiliares 
					//para llenar los jugadores goleadores de casa y visitantes
					asignarGoles(au1, cod,this.auxJugador);
					au2=generarGoles();
					asignarGoles(au2,cod2,this.auxJugador2);
					
					//se llenan las variables locales con la informacion de los partidos
					// sacando la informacion de los arraylist auxiliares que contiene
					//toda la informacion de una semana de juegos
					
					codigo = this.codigo.get(i);
					//controlarfecha es un indice que controla el arraylist auxiliar
					//que contiene todas las fechas de todos los partidos
					// es un indice aparte porque todas los juegos de una semana
					// se generan el mismo dia
					fecha= this.fechas.get(controlarfecha);
					// asigna el equipo casa de la semana 
					casa= this.casa.get(g);
					// asigna el equipo visitante de la semana
					visita = this.visita.get(g);
				    //asigna el arbitro de la semana
					arbitro= this.Auxarbitro.get(g);
					Partido partido = new Partido(codigo,fecha,casa,visita,arbitro,this.auxJugador,this.auxJugador2,au1,au2);
					//genera partido
					cargarPartido(partido);
					//como son varios partidos en una semana
					//se debe incrementar la i que controla el total de
					//partidos que se van a generar en toda la liga
					
					++i;
					//incrementa la g que controla el total de partidos que se
					//guardan en una semana
					++g;
				
					
				}
				//como ya se lleno una semana se debe mover el indice
				//que controla el arraylist auxiliar de fechas
				//para que asigne la fecha de la semana siguiente
				++controlarfecha;
			
				
					
					
				
				
				
			}
		}
//para actualizar la clase jugadores,arbitros y equipo
public void actualizar()
 {
	//for que recorre todo el arraylist partido para actualizar los datos
	// la informacion que se genero en partidos
	for(int i=0;i<this.contarPartidos();++i)
	{
		//actualizando equipo
		//variables locales para asignar la posicion
		// y marcadores me contienen el total de goles que
		// se les fue asignado a un equipo
		int posicion,posicion2,marcadorcasa,marcadorvisitante;
		String cod,cod2;
		//se les asigna a las variables locales los codigo de los equipos
		//para posteriormente ser buscadas en el arraylist que contiene todos los equipos
		cod= this.Partidos.get(i).getEquipocasa().getCodigo();
		cod2=this.Partidos.get(i).getEquipovisitante().getCodigo();
		//se utiliza los metodos de buscar que retornan una posicion
		//donde se encentra el equipo
		posicion= buscarEquipo(cod);
		posicion2=buscarEquipo(cod2);
		// se actualiza el atributo juegos jugados
		this.Equipos.get(posicion).setJuegosJugados(1);
		this.Equipos.get(posicion2).setJuegosJugados(1);
		//asigna los goles que fueron asignado a cada equipo
		marcadorcasa = this.Partidos.get(i).getMarcador1();
		marcadorvisitante = this.Partidos.get(i).getMarcador2();
		//se actualizan los atributos de los goles en contras y a favor
		//de los dos equipos
		
		 this.Equipos.get(posicion).setGolesFavor(marcadorcasa);
		 this.Equipos.get(posicion).setGolesContra(marcadorvisitante);
		 this.Equipos.get(posicion2).setGolesFavor(marcadorvisitante);
		 this.Equipos.get(posicion2).setGolesContra(marcadorcasa);
		 //pregunta con los goles para verificar quien gana y quien perdio
		 //en el partido y actualiza los atributos
		
		 if(marcadorcasa>marcadorvisitante)
		 {
			 this.Equipos.get(posicion).setJuegosGanados(1);
			 this.Equipos.get(posicion2).setJuegosPerdidos(1);
			
			 
		 }
		 else
			 if(marcadorcasa==marcadorvisitante)
			 {
				 this.Equipos.get(posicion).setJuegosEmpatados(1);
				 this.Equipos.get(posicion2).setJuegosEmpatados(1);
				 
				 
			 }
			 else
				 if(marcadorcasa<marcadorvisitante)
				 {
					 this.Equipos.get(posicion).setJuegosPerdidos(1);
					 this.Equipos.get(posicion2).setJuegosGanados(1);
				 }
		 
		 
		 //actualizar arbitro
		 //variables locales
		 
		 int posicion3;
		 String cedula;
		 // asigna a la variable local la cedula del arbitro para
		 //buscarlo en el arraylist que contiene todos los arbitros
		 
		  cedula= this.Partidos.get(i).getArbitro().getCedula();
		  // se utiliza el metodo que busca un arbitro en el arraylist que contiene
		  //todos los arbitros y retorna la posicion donde se encuentra
		  posicion3= buscarArbitro(cedula);
		  // le actualiza el atributo de cantidad dejuegos arbitrados
		  
		  this.Arbitros.get(posicion3).setCantidadpartidos(1);
		  
		  //actualizando jugador
		  //jugadores que anotaron gol en casa
		  //for que me controla el total de jugadores a los que se le va a asignar los goles
		  
		  
		  for(int j=0;j<this.Partidos.get(i).getGolescasa().size();++j)
			  
		  {
			  //asigna la cedula a una variable local
			  cedula= this.Partidos.get(i).getGolescasa().get(j).getCedula();
			  // utiliza el metodo buscar jugador y retorna la posicion
			  posicion3=buscarJugador(cedula,posicion);
			  //actualiza el artributo de goles anotados 
			  this.Equipos.get(posicion).getJugadores().get(posicion3).setGolesanotados(1);
			  
			  
		  }
		  //jugadores que anotaron gol en visitante
		  for(int j=0;j<this.Partidos.get(i).getGolesvisitantes().size();++j)
		  {
			  cedula= this.Partidos.get(i).getGolesvisitantes().get(j).getCedula();
			  posicion3=buscarJugador(cedula,posicion2);
			  this.Equipos.get(posicion2).getJugadores().get(posicion3).setGolesanotados(1);
			  
			  
		  }
		 
		 
		 
		 
		
	}
	}

//ordena el arraylist de equipos por el total de puntos

   public void equiposOrdenados (){
	   //auxiliares locales
	   
	   Equipo aux1, aux2;
	   
	   for (int i=0 ; i < contarequipo(); ++i){
		   
		   for (int j = i+1; j< contarequipo(); ++j){
			   
			   if (this.Equipos.get(i).getPuntos() < this.Equipos.get(j).getPuntos()){
				   
				   aux1 = this.Equipos.get(i);
				   aux2 = this.Equipos.get(j);
				   this.Equipos.set(i, aux2);
				   this.Equipos.set(j, aux1);
			   }
			   
		   }
	   }
	   
   }
   //ordena el arraylist equipo por diferencia de goles
   
public void equiposOrdenadosDiferencia (){
	//variables locales
	   
	   Equipo aux1, aux2;
	   int j=0, i =0;
	   
	   while (i < this.contarequipo()-1){
		   
		 
		 
		   
		    j = i+1; 
			   
			   if ((this.Equipos.get(i).getPuntos()) == (this.Equipos.get(j).getPuntos())){
				   
				   if ((Equipos.get(i).diferenciaGoles()) < (Equipos.get(j).diferenciaGoles())){
					   
					   aux1 = this.Equipos.get(i);
					   aux2 = this.Equipos.get(j);
					   this.Equipos.set(i, aux2);
					   this.Equipos.set(j, aux1);
					   ++i;
					   
					   
				   }
				   
				   else
					   ++i;
				   
					   
				   
			
			   }
			   else
				   ++i;
			   
		   }
	    
    
	   
    }


}

		
		

	
	
	
		
		
		
		
	
	
	
	
	
	
	
	

